package com.fingard.dsp.bank.directbank.pab02.Util.api.bean;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.fingard.dsp.bank.directbank.pab02.Util.api.exception.FtpErrCode;
import com.fingard.dsp.bank.directbank.pab02.Util.api.exception.FtpException;
import com.fingard.dsp.bank.directbank.pab02.Util.api.ftp.http.FtpConnector;

import java.io.InputStream;

/**
 * @author created by pj
 * @date 2018年8月8日下午2:39:31 客户端，文件上传类
 */
public class FtpPut {

	private String remoteFileName = null;
	private String localFileName = null;
	private FtpConnector conn = null;
	private EsbFile file = null;
	private FileMsgBean bean = null;

	/**
	 * 进行用户口令及文件读取权限的认证,返回对象的authFlag等于true则认证成功，否则认证失败
	 * 
	 * @return FileMsgBean，文件消息对象，认证结果存放在该对象中
	 */
	private FileMsgBean doAuth() throws FtpException {
		bean.setFileMsgFlag(FileMsgType.PUT_AUTH);

		InputStream in = conn.sendRequest(conn.beanToBytes(bean));
		conn.readHead(bean, in);

		close(false);
		return bean;
	}

	/**
	 * 构造函数，进行的处理包括：1、文件本地文件对象的创建；2、进行用户的认证处理
	 * 
	 * @param bean
	 *            文件请求包装类
	 * @throws FtpException
	 */
	public FtpPut( FileMsgBean bean ) throws FtpException {

		this.remoteFileName = bean.getRemotePath();
		this.localFileName = bean.getLocalPath();
		// 创建上传的文件
		file = new EsbFile(bean.getLocalPath(), EsbFile.CLIENT);

		this.bean = bean;
		bean.setFileName(remoteFileName);
		bean.setClientFileName(localFileName);
		bean.setFileSize(file.getSize());

		// 建立与服务器的连接
		conn = new FtpConnector(bean.getFileServerUrl());

		// 进行用户口令及文件读取权限的认证
		this.doAuth();
		if (!FileMsgType.PUT_AUTH.equals(bean.getFileMsgFlag())) {
			throw new FtpException(bean.getFileMsgFlag());
		}
		if (!bean.isAuthFlag()) {
			bean.setFileRetMsg(FtpErrCode.getCodeMsg(FtpErrCode.AuthUserFailed));
			throw new FtpException(FtpErrCode.AuthUserFailed);
		}

		if (bean.isAuthTokenFlag()) {
			file.openForRead(0);
		} else {
			bean.setFileRetMsg(FtpErrCode.getCodeMsg(FtpErrCode.AuthTokenFailed));
			throw new FtpException(FtpErrCode.AuthTokenFailed);
		}
	}

	/**
	 * 进行文件的上传处理
	 * 
	 * @return 返回文件的名称
	 * @throws FtpException
	 */
	public FileMsgBean doPutFile() throws FtpException {
		try {
			bean.setFileIndex(0);
			//文件断点续传功能
			if (bean.isContinueFlag()) {
				for (int i = 0; i < bean.getStartPiece(); i++) {
					bean.addFileIndex();
					file.fillMd5(bean);
				}
				file.openForRead(bean.getStartPiece() * bean.getPieceNum());
				System.out.println("结束修正");
			}

			// 设置文件上传的数据
			while (true) {
				// 读取本地文件一个分片
				bean.setFileMsgFlag(FileMsgType.PUT);
				bean.addFileIndex();
				file.read(bean);
				// 写入消息头和文件的内容
				InputStream in = conn.sendRequest(conn.putFileToBytes(bean));
				// 读取响应的头信息
				conn.readHead(bean, in);
				if (!FileMsgType.SUCC.equals(bean.getFileMsgFlag())) {
					throw new FtpException(bean.getFileMsgFlag());
				}
				if (bean.isLastPiece()) {
					close(true);
					break;
				}
			}
			// 返回文件的名称
			return bean;
		} catch (Exception e) {
			if (e instanceof FtpException) {
				throw (FtpException) e;
			} else {
				throw new FtpException(FtpErrCode.FileUpError);
			}
		} finally {
			close(true);
		}
	}

	/**
	 * 结束文件的上传处理，关闭连接对象和本地文件
	 */
	public void close(boolean closeFile) {

		if (file != null && closeFile)
			try {
				file.close();
			} catch (FtpException e) {

			}
	}

}
